﻿using System;
using Super_Management_Mayhem.Content.Animations;
using Super_Management_Mayhem.Content.Spritesheet;
using Super_Management_Mayhem.Screens.Playing.AttackModel;
using Super_Management_Mayhem.Screens.Playing.ObjectInterfaces;
using Super_Management_Mayhem.Screens.Playing.Particle.Explosion;
using Super_Management_Mayhem.Screens.Playing.Particle.Smoke;
using Super_Management_Mayhem.Screens.Playing.Players;
using Super_Management_Mayhem.Screens.Playing.Players.Manager;
using Transformable_Engine_v2.Engine.Animation.FrameAnimation;
using Transformable_Engine_v2.Engine.Animation.PositionAnimation;
using Transformable_Engine_v2.Engine.Animation.Queue;
using Transformable_Engine_v2.Engine.Animation.Trajectory;
using Transformable_Engine_v2.Engine.GameObjects.Containers;
using Transformable_Engine_v2.Engine.Graphics;
using Transformable_Engine_v2.Engine.Time;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Super_Management_Mayhem.Screens.Playing.Items
{
    public class ThrownBomb : Container, IOrderable
    {
        public ThrownBomb(TE_Vector2 direction)
        {
            var item = new ImageContainer
            {
                Sprite = ItemSheet.GetSprite(ItemSheet.Item.Bomb),
                Origin = TE_Rectangle.Alignment.CenterMiddle
            };
            item.AddAnimations(new FrameAnimation(new BombLongFuse()));

            var smokeStream = new SmokeStream(50)
            {
                PositionGridBound = new TE_Vector2(0, -0.25f)
            };

            AddChildren(item, smokeStream);

            AddAnimations(new PositionAnimation(new BounceEasing(BaseTrajectory.Easing.EaseOut), new TE_Vector2(0, 2), 600, false, 0));
            AddAnimations(new PositionAnimation(new QuadraticEasing(BaseTrajectory.Easing.EaseOut), direction * 7, 600, false, 0));
            Die(600);
        }

        public override void Die()
        {
            //Go out with a boom!
            Playscreen.Map.AddParticle(new Explosion(AbsolutePosition));

            base.Die();
        }

        public float GetOrderingFactor()
        {
            return Position.Y;
        }

        private static readonly TE_Rectangle HitBoundingBox =
            new TE_Rectangle(0, 0, 1, 1, TE_Rectangle.Alignment.CenterMiddle).ToGridBound();
        public TE_Rectangle GetBoundingBoxCollision()
        {
            return HitBoundingBox;
        }

        public bool Hit(TE_Vector2 direction, int time, TE_Vector2 sourceObjectPosition)
        {
            Die();
            return true;
        }
    }

    public class PickedUpBomb : Container, IThrowable
    {
        

        private const int BOMB_TICK_TIME = 1500;
        private int _bombCounter;

        private Timer _bombTimer;

        private ImageContainer _item;

        private SmokeStream _smokeStream;

        public override void LoadContent()
        {
            _item = new ImageContainer {
                                           Sprite = ItemSheet.GetSprite(ItemSheet.Item.Bomb),
                                           Origin = TE_Rectangle.Alignment.CenterMiddle
                                       };
            _bombCounter = 0;
            _item.AddAnimations(new FrameAnimation(new BombLongFuse()));

            _smokeStream = new SmokeStream(200)
                               {
                                   PositionGridBound = new TE_Vector2(0, -0.25f)
                               };

            AddChildren(_item, _smokeStream);

            _bombTimer = new Timer(BOMB_TICK_TIME, true, BombTick);
            _bombTimer.Start();

            AddTimers(_bombTimer);

            

            base.LoadContent();
        }

        private void BombTick()
        {
            _bombCounter++;
            _item.ClearAnimation<FrameAnimation>();
            switch (_bombCounter)
            {
                case 1:
                    _item.AddAnimations(new FrameAnimation(new BombMediumFuse()));
                    _smokeStream.ChangeSmokeTickTime(100);
                    break;
                case 2:
                    _item.AddAnimations(new FrameAnimation(new BombShortFuse()));
                    _smokeStream.ChangeSmokeTickTime(50);
                    break;
                case 3:
                    _item.Visible = false;
                    //Boom!
                    Playscreen.Map.AddParticle(new Explosion(AbsolutePosition));
                    Die();
                    break;
            }
        }

        public void Throw(TE_Vector2 throwerPosition, TE_Vector2 itemPosition, Manager.Direction latestDirection, Team team)
        {
            TE_Vector2 direction = null;

            switch (latestDirection)
            {
                case Manager.Direction.Up:
                    direction = -TE_Vector2.UnitY;
                    break;
                case Manager.Direction.Down:
                    direction = TE_Vector2.UnitY;
                    break;
                case Manager.Direction.Left:
                    direction = -TE_Vector2.UnitX;
                    break;
                case Manager.Direction.Right:
                    direction = TE_Vector2.UnitX;
                    break;
            }

            Playscreen.Map.AddItem(new ThrownBomb(direction) { Position = itemPosition });
        }
    }

    public class IdleBomb : BasePickableItem, IAttackable
    {
        protected override int ReappearTime
        {
            get
            {
                return 5000;
            }
        }

        public override void LoadContent()
        {
            _item = new ImageContainer {
                                           Sprite = ItemSheet.GetSprite(ItemSheet.Item.Bomb),
                                       };

            _item.AddAnimations(new LoopingAnimationQueue(0, true,
                                                          new PositionAnimation(new QuadraticEasing(BaseTrajectory.Easing.EaseOut), new TE_Vector2(0, -0.25f), 250, false, 2000),
                                                          new PositionAnimation(new BounceEasing(BaseTrajectory.Easing.EaseOut), new TE_Vector2(0, 0), 500, false, 0)));


            _outline = new ImageContainer {
                                              Sprite = ItemSheet.GetSprite(ItemSheet.ItemOutline.BombOutline),
                                          };

            _outline.AddAnimations(new LoopingAnimationQueue(0, true,
                                                             new PositionAnimation(new QuadraticEasing(BaseTrajectory.Easing.EaseOut), new TE_Vector2(0, -0.25f), 250, false, 2000),
                                                             new PositionAnimation(new BounceEasing(BaseTrajectory.Easing.EaseOut), new TE_Vector2(0, 0), 500, false, 0)));

            AddChildren(_item, _outline);

            base.LoadContent();
        }

        protected override IThrowable GetPickupItem()
        {
            return new PickedUpBomb();
        }

        public Container GetReference()
        {
            return this;
        }

        public bool Hit(TE_Vector2 direction, TE_Vector2 attackerPosition, int hurtTime, int damage)
        {
            if (_item.Visible)
            {
                Pickup();
                Playscreen.Map.AddParticle(new Explosion(AbsolutePosition.Offset(8, 8)));
                return true;
            }

            return false;
        }

        public Team GetTeam()
        {
            return null;
        }
    }
}
